// 创造画布
const canvas = wx.createCanvas();
// 获取上下文 (画笔?)
const context = canvas.getContext("2d");
// 获取屏幕长宽
const {
  windowWidth,
  windowHeight,
  pixelRatio,
} = wx.getSystemInfoSync();

canvas.width  = canvas.width  * pixelRatio;
canvas.height = canvas.height * pixelRatio;
context.scale(pixelRatio, pixelRatio);

// 获取缩放后的背景图 x, y
let BgImage = wx.createImage();
let BgImageLoad = false;
BgImage.onload = function () {
  BgImageLoad = true;
}
BgImage.src = "img/bg.png";
const BgImgX = 1280;
const BgImgY = 720;



// 创造各种全局常量变量
const screenX       = windowWidth;
const screenY       = windowHeight;
const v_Aphid       = 2.5; // 蚜虫速度
const v_Frog        = 1.1;  // 青蛙速度
const eatAward      = 35;   // 吃蚜虫奖励生命
const acceMultiply  = 1.3;  // 加速度按一定比例扩大
const heartLose     = 0.15;
const heartMax      = 200;
let   heart         = 200;
let   timeTick      = 0;    // 时钟, 暂时只有随时间改变颜色的作用
let   over          = 0;    // 游戏是否结束
let   start         = 0;    // 游戏是否开始
let   score         = 0;
let   max_score     = 0;
let   accelerateX   = 0;
let   accelerateY   = 0;
let   vLadybugX     = 0;
let   vLadybugY     = 0;
let   vAphidX       = 0;
let   vAphidY       = 0;
let   vFrogX        = 0;
let   vFrogY        = 0;
let   LUX           = 0;    // 左上 x, y
let   LUY           = 0;
let   RDW           = 0;    // 绘制宽度
let   RDH           = 0;    // 绘制高度



function adjustBg() {
  // 图片宽于屏幕，左右各裁剪一部分
  if (BgImgX / BgImgY > screenX / screenY) {
    // let bgH = BgImgY / BgImgY * screenY;
    let bgW = BgImgX / BgImgY * screenY;
    let diffW = (bgW - screenX) / 2;
    LUX = -diffW;
    LUY =  0;
    RDW =  bgW;
    RDH =  screenY;
  } else { // 上下各裁剪一部分
    let bgH = BgImgY / BgImgX * screenX;
    // let bgW = BgImgX / BgImgX * screenX;
    let diffH = (bgH - screenY) / 2;
    LUX =  0;
    LUY = -diffH;
    RDW =  screenX;
    RDH =  bgH;
  }
  console.log("BgImgX:" + BgImgX + ", BgImgY:" + BgImgY);
  console.log(BgImage.src);
  console.log("LUX:" + LUX + ", LUY:" + LUY + ", RDW:" + RDW + ", RDH:" + RDH);
}
adjustBg();



// 创造瓢虫
let LadybugImage = wx.createImage();
let LadybugImgLoad = false;
let LadybugX = screenX / 2 - 15;
let LadybugY = screenY / 4 * 3 - 15;
LadybugImage.onload = function () {
  LadybugImgLoad = true;
}
LadybugImage.src = "img/ladybug_fixed.png";



// 创造蚜虫
let AphidImage = wx.createImage();
let AphidImgLoad = false;
let AphidX = screenX / 3 - 15;
let AphidY = screenY / 2 - 15;
AphidImage.onload = function () {
  AphidImgLoad = true;
}
AphidImage.src = "img/aphid_fixed2.png";



// 创造青蛙
let FrogImage = wx.createImage();
let FrogImgLoad = false;
let FrogX = screenX / 3 * 2 - 15;
let FrogY = screenY / 2 - 15;
FrogImage.onload = function () {
  FrogImgLoad = true;
}
FrogImage.src = "img/frog_fixed.png";



// 创造速度传感器, 每 20ms 更新加速度数据
wx.startAccelerometer({
  success: () => {
    console.log("Start accelerometer success");
    console.log("screenX:" + screenX + ", screenY:" + screenY);
  },
  interval: "game"
});
wx.onAccelerometerChange((res) => {
  accelerateX = -res.y * acceMultiply;
  accelerateY = -res.x * acceMultiply;
});
// 但是每 5ms 就更新速度数据, 使速度的变化更平滑,
// 当然每次加速度变为 1/5
// 纵轴变化 1/5 的 4/3 倍, 是为了减小纵向倾斜的幅度
setInterval(() => {
  vLadybugX  += accelerateX * 0.20;
  vLadybugY  += accelerateY * 0.266666;
}, 5);



// 移动瓢虫
function moveLadybug() {
  LadybugX += vLadybugX;
  LadybugY += vLadybugY;
  // 不能超出边界 && 轻微弹墙效果
  if ( LadybugX <      16)
    {  LadybugX =      16;
      vLadybugX = -vLadybugX * 0.45; }
  if ( LadybugY <      16)
    {  LadybugY =      16;
      vLadybugY = -vLadybugY * 0.45; }
  if ( LadybugX > screenX - 16)
    {  LadybugX = screenX - 16;
      vLadybugX = -vLadybugX * 0.45; }
  if ( LadybugY > screenY - 16)
    {  LadybugY = screenY - 16;
      vLadybugY = -vLadybugY * 0.45; }
  // 扣血
  if (start) { heart -= heartLose; }
}



// 随机函数, 生成 [a, b) 的整数
function randRange(a, b) {
  let diff = b - a;
  let bigInt = Math.round(Math.random() * 1000000);
  return a + bigInt % diff;
}
// 移动蚜虫, 主循环 15ms, 随机改变方向, 期望 135ms 改一次, 因此概率 11%
function moveAphid() {
  let dirChange = randRange(0, 100);
  if (dirChange < 11) {
    let dirDegree = randRange(0, 360);
    vAphidX =  Math.cos(dirDegree) * v_Aphid;
    vAphidY = -Math.sin(dirDegree) * v_Aphid;
  }
  AphidX += vAphidX;
  AphidY += vAphidY;
  // 不能超出边界
  if ( AphidX <    16)
    {  AphidX =    16;
      vAphidX = -vAphidX; }
  if ( AphidY <    16)
    {  AphidY =    16;
      vAphidY = -vAphidY; }
  if ( AphidX > screenX - 16)
    {  AphidX = screenX - 16;
      vAphidX = -vAphidX; }
  if ( AphidY > screenY - 16)
    {  AphidY = screenY - 16;
      vAphidY = -vAphidY; }
}



// 移动青蛙, 主循环 15ms, 随机改变方向, 期望 300ms 改一次, 其中大概率跟随, 小概率随机
function moveFrog() {
  let dirChange = randRange(0, 1000);
  if (dirChange < 60) {
    // 直角三角形的三边
    let diffX = LadybugX - FrogX;
    let diffY = LadybugY - FrogY;
    let hypotenuse = Math.sqrt(diffX * diffX + diffY * diffY);
    vFrogX = diffX / hypotenuse * v_Frog;
    vFrogY = diffY / hypotenuse * v_Frog;
    // console.log("diffX:" + diffX + ", diffY:" + diffY);
  } else if (dirChange < 72) {
    let dirDegree = randRange(0, 360);
    vFrogX =  Math.cos(dirDegree) * v_Frog;
    vFrogY = -Math.sin(dirDegree) * v_Frog;
  }
  FrogX += vFrogX;
  FrogY += vFrogY;
  // 不能超出边界
  if ( FrogX <    24)
    {  FrogX =    24;
      vFrogX = -vFrogX; }
  if ( FrogY <    24)
    {  FrogY =    24;
      vFrogY = -vFrogY; }
  if ( FrogX > screenX - 24)
    {  FrogX = screenX - 24;
      vFrogX = -vFrogX; }
  if ( FrogY > screenY - 24)
    {  FrogY = screenY - 24;
      vFrogY = -vFrogY; }
}



// 处理碰撞逻辑, 坐标都是中心坐标, 碰撞后进行回调
function whenCollision(x1, y1, x2, y2, distance, callback) {
  if ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) < distance * distance) { callback(); }
}



// 回调: 吃蚜虫, 在游戏没开始时的行为是被弹飞
function eatAphid() {
  if (over) { return; }
  if (!start) {
    // 直角三角形的三边
    let diffX = LadybugX - AphidX;
    let diffY = LadybugY - AphidY;
    let hypotenuse = Math.sqrt(diffX * diffX + diffY * diffY);
    vLadybugX = diffX / hypotenuse * 125;
    vLadybugY = diffY / hypotenuse * 125;
    return;
  }
  heart += eatAward;
  ++score;
  if (heart > 200) { heart = 200; }
  AphidX = randRange(0, screenX);
  AphidY = randRange(0, screenY);
}
// 回调: 被青蛙吃, 在游戏没开始时的行为是被弹飞
function eatenByFrog() {
  if (!start) {
    // 直角三角形的三边
    let diffX = LadybugX - FrogX;
    let diffY = LadybugY - FrogY;
    let hypotenuse = Math.sqrt(diffX * diffX + diffY * diffY);
    vLadybugX = diffX / hypotenuse * 125;
    vLadybugY = diffY / hypotenuse * 125;
    return;
  }
  heart = 0;
  over  = 1;
}



// 游戏开始
function startGame() {
  heart = 200;
  start = 1;
}



// 返回标题
function backToStart() {
  timeTick  = 0;
  vLadybugX = 0;
  vLadybugY = 0;
  score     = 0;
  max_score = wx.getStorageSync("max_score");
  if (!max_score) { max_score = 0;
    wx.setStorageSync("max_score", 0); }
  LadybugX  = screenX / 2 - 15;
  LadybugY  = screenY / 4 * 3 - 15;
  AphidX    = screenX / 3 - 15;
  AphidY    = screenY / 2 - 15;
  FrogX     = screenX / 3 * 2 - 15;
  FrogY     = screenY / 2 - 15;
  vAphidX   = -1;
  vAphidY   = -1;
  vFrogX    = -1;
  vFrogY    = 0.5;
  start     = 0;
  over      = 0;
  LadybugImage.src = "img/ladybug_fixed.png";
}
backToStart();



// 游戏结束
function gameOver() {
  LadybugImage.src = "img/dead_fixed.png";
}



// 更新画布, 画出所有看得到的东西
function updateCanvas() {
  context.clearRect(0, 0, screenX, screenY);
  context.drawImage(BgImage, LUX, LUY, RDW, RDH);
  if (start) {
    context.fillStyle = "#F04777"; // 红色
    context.fillRect(120, 0, screenX - 150, 30);
    context.fillStyle = "#08E770"; // 绿色
    context.fillRect(120, 0, (screenX - 150) * heart / heartMax, 30);
    if (!over) {
      context.fillStyle = "#F5EE16"; // 黄色
      context.textAlign = "center";
      context.font = "22px sans-serif";
      context.fillText("分数: " + score, 65, 24);
    }
  } else {
    context.fillStyle = "#FF9500"; // 橙色
    context.textAlign = "center";
    context.font = "75px sans-serif";
    context.fillText("瓢虫快跑", screenX / 2, screenY / 3);
    timeTick += 0.04;
    // 在 #F04777 (红色, 240,  71, 119)
    // 和 #05BBFF (蓝色,   5, 187, 251) 之间渐变
    //          (中间色: 122, 129, 185)
    const __r = 122; const diff_r = 118;
    const __g = 129; const diff_g = -58;
    const __b = 185; const diff_b = -66;
    let  nowr = Math.round(__r + Math.sin(timeTick) * diff_r).toString(16);
    let  nowg = Math.round(__g + Math.sin(timeTick) * diff_g).toString(16);
    let  nowb = Math.round(__b + Math.sin(timeTick) * diff_b).toString(16);
    if (nowr.length < 2) { nowr = "0" + nowr; }
    if (nowg.length < 2) { nowg = "0" + nowg; }
    if (nowb.length < 2) { nowb = "0" + nowb; }
    let color = "#" + nowr + nowg + nowb;
    // console.log(color);
    context.fillStyle = color;
    context.textAlign = "center";
    context.font = "24px sans-serif";
    context.fillText("点击屏幕开始游戏", screenX / 2, screenY / 3 * 2 + 30);
    if (max_score) {
      context.fillStyle = "#F5EE16"; // 黄色
      context.font = "26px sans-serif";
      context.fillText("最高分: " + max_score, screenX / 2, screenY / 3 * 1.88);
    }
  }
  if (over) {
    context.fillStyle = "#C3C3C3"; // 灰色
    context.textAlign = "center";
    context.font = "60px sans-serif";
    if (max_score < score) {
      wx.setStorageSync("max_score", score);
      context.fillText("游戏结束", screenX / 2, screenY / 3 + 36);
      context.fillStyle = "#F5EE16"; // 黄色
      context.font = "22px sans-serif";
      context.fillText("新纪录！", screenX / 3 * 2.1, screenY / 3 * 1.05);
      context.font = "26px sans-serif";
      context.fillText("分数: " + score,       screenX / 2, screenY / 3 * 2);
      context.fillText("最高分: " + score, screenX / 2, screenY / 3 * 2 + 30);
    } else {
      context.fillText("游戏结束...", screenX / 2, screenY / 3 + 36);
      context.font = "26px sans-serif";
      context.fillText("分数: " + score,       screenX / 2, screenY / 3 * 2);
      context.fillText("最高分: " + max_score, screenX / 2, screenY / 3 * 2 + 30);
    }
  }
  context.save();
  context.translate(LadybugX, LadybugY);
  context.rotate(Math.atan2(vLadybugY, vLadybugX));
  context.drawImage(LadybugImage, -16, -16);
  context.restore();

  context.save();
  context.translate(AphidX, AphidY);
  context.rotate(Math.atan2(vAphidY, vAphidX));
  context.drawImage(AphidImage, -16, -16);
  context.restore();

  context.save();
  context.translate(FrogX, FrogY);
  context.rotate(Math.atan2(vFrogY, vFrogX));
  context.drawImage(FrogImage, -24, -24);
  context.restore();
}



// 主循环, 15ms 的时钟, 每次计时完成就更新画布
setInterval(() => {
  if (over == 1) { gameOver(); }
  if (start) {
    moveAphid();
    moveFrog();
  }
  if (!over) {
    moveLadybug();
  }
  whenCollision(LadybugX, LadybugY, AphidX, AphidY, 30, eatAphid);
  whenCollision(LadybugX, LadybugY, FrogX,  FrogY,  40, eatenByFrog);
  if (heart < 0) { heart = 0; over = 1; }
  updateCanvas();
}, 15);



// 测试
function debug() {
  console.log("start: " + start + ", over: " + over);
}
// 开始界面中点击开始, 结束后点击返回开始界面
wx.onTouchEnd(() => {
  if (start == 0) { startGame();   debug();}
  if (over  == 1) { backToStart(); debug(); }
});
